//: Playground - noun: a place where people can play

import UIKit

//class Student:NSCopying {
//    var name: String
//    required init(name:String){
//        self.name = name
//    }
//    func copy(with zone: NSZone? = nil) -> Any {
//        let student = Student(name: self.name)
//        return student
//    }
//}
//// 使用
//let student1 = Student(name: "1111")
//// 由于NSCopying 协议里面的方法copy 返回的值为Any 系统没法推断出来是Student 类型,所以必须 as! 指明是Student 类型 过程有点繁琐
//let student2:Student = student1.copy() as! Student
//student2.name = "2222"
//print(student1.name)
//print(student2.name)


// type(of: self) 获取到自身类的类型,然后通过init(name:self.name) 初始化一个对象 ,初始化的对象为Self 类型
class Student{
    var name: String
    required init(name:String){
        self.name = name
    }
    func copy() -> Self {
        let result = type(of: self).init(name:self.name)
        return result
    }
    
//    func copy() -> Student{
//        let result = Student.self.init(name:self.name)
//        return result
//    }
//    
//    func copy() -> Student{
//        let result = Student.init(name: self.name)
//        return result
//    }
//    
//    func copy() -> Student{
//        let result = Student(name: self.name)
//        return result
//    }
}
// 使用
let student1 = Student(name: "111")
let student2 = student1.copy()
student2.name = "2222"
print(student1.name)
print(student2.name)


// 定义个协议
protocol NumberProtocol{
}
// 扩展实现协议
extension Int:NumberProtocol{
}
extension Double:NumberProtocol{
}
// 给协议扩展方法
extension NumberProtocol{
    // 我们不确定返回的Self 到底是什么类型
    func squareValue()-> Self{
        if self is Int{
            let n = self as! Int
            return n * n as! Self
        }
        if self is Double{
            let n = self as! Double
            return n * n as! Self
        }
        return 0 as! Self
    }
}
print(3.44.squareValue())
print(3.squareValue())

